﻿using System;
using System.Drawing;
using System.Globalization;
using System.Text.RegularExpressions;

namespace Jayden.Dll.Web.Helper
{
	public sealed class HtmlHelper
	{
		public const string MimeType = "text/html";
		public const string Html5Doctype = "<!DOCTYPE html>";

		public const string Blank = "_blank";
		public const string Self = "_self";
		public const string Parent = "_parent";
		public const string Top = "_top";

		public const string Zero = "0";
		public const string EmptyUrl = "about:blank";

		public const string InputEmailPattern = @"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$";

		public const string ApplicationFormUrlEncoded = "application/x-www-form-urlencoded";
		public const string MultipartFormData = "multipart/form-data";
		public const string TextPlain = "text/plain";

		public static string ToHtmlWeek(DateTime dateTime)
		{
			int weekOfYear = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
			int year = CultureInfo.InvariantCulture.Calendar.GetYear(dateTime);
			if (dateTime.Month == 1 && weekOfYear > 50)
				year--;
			if (dateTime.Month == 12 && weekOfYear < 4)
				year++;
			return year.ToString().PadLeft(4, '0') + "-W" + weekOfYear.ToString().PadLeft(2, '0');
		}
		public static string ToHtmlMonth(DateTime dateTime) { return dateTime.ToString("yyyy-MM"); }
		public static string ToHtmlDate(DateTime dateTime) { return dateTime.ToString("yyyy-MM-dd"); }
		public static string ToHtmlTime(DateTime dateTime, bool seconds = false, bool millisec = false)
		{
			string format = "HH:mm";
			if (seconds)
			{
				format += ":ss";
				if (millisec)
					format += ".ff";
			}
			return dateTime.ToString(format);
		}
		public static string ToHtmlDateTime(DateTime dateTime, bool local = true)
		{
			string format = "{0}T{1}";
			if(!local)
				format += "Z";
			return string.Format(format, ToHtmlDate(dateTime), ToHtmlTime(dateTime));
		}

		public static DateTime FromHtmlDateTime(string dateTime)
		{
			//return DateTime.ParseExact(dateTime, "yyyy-MM-dd\\THH-mm\\Z", CultureInfo.InvariantCulture);
			return DateTime.Parse(dateTime, CultureInfo.InvariantCulture);
		}
		public static DateTime FromHtmlDateTime(string dateTime, DateTime defaultValue)
		{
			try
			{
				return FromHtmlDateTime(dateTime);
			}
			catch
			{
				return defaultValue;
			}
		}
		public static DateTime FromHtmlDate(string dateTime, DateTime defaultValue)
		{
			try
			{
				return DateTime.Parse(dateTime, CultureInfo.InvariantCulture);
			}
			catch
			{
				return defaultValue;
			}
		}
		public static DateTime FromHtmlMonth(string dateTime) { return DateTime.Parse(dateTime, CultureInfo.InvariantCulture); }
		public static DateTime FromHtmlTime(string dateTime) { return DateTime.Parse(dateTime, CultureInfo.InvariantCulture); }
		public static DateTime FromHtmlWeek(string dateTime)
		{
			string[] parts = dateTime.Split(new string[] { "-W" }, StringSplitOptions.RemoveEmptyEntries);
			int year = int.Parse(parts[0]);
			int weekOfYear = int.Parse(parts[1]);
			DateTime dateWeek = new DateTime(year, 1, 1);
			int currentWeekOfYear = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(dateWeek, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
			while (currentWeekOfYear > 50)
			{
				dateWeek = dateWeek.AddDays(1);
				currentWeekOfYear = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(dateWeek, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
			}
			while (currentWeekOfYear < 4)
			{
				dateWeek = dateWeek.AddDays(-1);
				currentWeekOfYear = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(dateWeek, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
			}
			if (currentWeekOfYear > 50)
				dateWeek = dateWeek.AddDays(1);
			dateWeek = dateWeek.AddDays(7 * weekOfYear);
			return dateWeek;
		}

		public static bool IsPattern(string pattern)
		{
			try
			{
				Regex regex = new Regex(pattern, RegexOptions.ECMAScript);
				return true;
			}
			catch (Exception e)
			{
				return false;
			}
		}

		public static string ToHtmlColor(Color color) { return ColorTranslator.ToHtml(color).ToLowerInvariant(); }
		public static Color FromHtmlColor(string htmlColor) { return ColorTranslator.FromHtml(htmlColor.Trim()); }

		public static string ToHtmlFloat(double? value) { return value.HasValue ? value.Value.ToString(CultureInfo.InvariantCulture) : null; }
		public static string ToHtmlPositiveFloat(double value) { return ToHtmlFloat(Math.Abs(value)); }

		public static double? FromHtmlFloat(string value)
		{
			if (value == null)
				return null;
			return double.Parse(value, CultureInfo.InvariantCulture);
		}

		public static bool IsToken(string text) { return !text.Trim().Contains(" "); }

		public static string ToPixels(object value)
		{
			return string.Format("{0}px", value);
		}
	}
}
